﻿namespace KLF.Lib.Browser.DOM.CSS.SAC.Conditions
{
    #region Using Statements

    using KLF.Lib.Browser.DOM.HTML;
    using System.Text.RegularExpressions;
    using System;
    using System.Collections.Generic;

    #endregion
    /// <summary>
    /// Checks to see if an element is the document root.
    /// </summary>
    public class PseudoNthChild : Condition
    {
        public static Regex Grammer = new Regex(@"\s*" +
            @"(?<F1>(?<nThP1>([-\+])?[\d]+){1}\s*N\s*(?<nThP2>([-\+])?[\d]+)){1}|" +
            @"(?<F2>([-\+])?[\d]+){1}|" +
            @"(?<F3>odd|even){1}",
            RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);

        public PseudoNthChild(string arg)
        {
            Match m = Grammer.Match(arg);

            if (m.Success)
            {
                if (m.Groups["F3"].Success)
                {
                    StepBy = 2;
                    ModStep = (m.Groups["F3"]
                        .Value
                        .ToLowerInvariant()
                        .Equals("odd") ? 1 : 0);
                }
                else if (m.Groups["F2"].Success)
                {
                    StepBy = 0;
                    ModStep = Convert.ToInt32(m.Groups["F2"].Value);
                }
                else if (m.Groups["F1"].Success)
                {
                    StepBy = Convert.ToInt32(m.Groups["nThP1"].Value);
                    ModStep = Convert.ToInt32(m.Groups["nThP2"].Value);
                }
                else
                {
                    throw new ArgumentException();
                }
            }
        }

        public int StepBy { get; set; }

        public int ModStep { get; set; }

        public override ConditionType Type
        {
            get { return ConditionType.PsueodoClassCondition; }
        }

        public override bool MatchElement(HTMLElement e)
        {
            if (e.Parent != null)
            {
                List<Node> nodes = e.Parent.Children;

                if (StepBy != 0)
                {
                    for (int i = StepBy; i <= nodes.Count; i += StepBy)
                    {
                        int n = i - ModStep;

                        if (n > -1 && n < nodes.Count)
                            if (nodes[n] == e)
                                return true;
                    }
                }
                else if (ModStep > 0)
                {
                    if (ModStep > 0)
                        return nodes[ModStep - 1] == e;
                }
            }
            return false;
        }

        public override string ToString()
        {
            return String.Format(":nth-child({0}n{1})", StepBy, ModStep);
        }
    }
}
